<?php

/**
 * This is the model class for table "yii_user".
 *
 * The followings are the available columns in table 'yii_user':
 * @property integer $id
 * @property string $username
 * @property string $password
 * @property string $email
 * @property string $first_name
 * @property string $last_name
 * @property integer $active
 * @property string $user_role
 * @property string $create_date
 * @property string $created_by
 * @property string $update_date
 * @property string $updated_by
 * @property string $confirm_password
 * @property string $full_name
 * The followings are the available model relations:
 * @property AuthAssignment[] $auth_assignments

 */
class User extends CActiveRecord {

	/**
	 * Returns the static model of the specified AR class.
	 * @param string $className active record class name.
	 * @return User the static model class
	 */
	public $search_role;
	public $new_password;
	public $new_password_repeat;
	public $auth_assignments;
	public $fullname;
	public $securityCode;

	/**
	 * It's includes username or name which are information for search function
	 * @var type String
	 */
	public $keyword;

	const SCENARIO_SEARCH = 'search';
	const SCENARIO_CREATE = 'create';
	const SCENARIO_UPDATE_USER = 'update';
	const SCENARIO_USER_REGISTER = 'user_register';
	const SCENARIO_CHANGE_ACTIVATION_STATUS = 'change_activation_status';

	/**
	 * Returns the static model of the specified AR class.
	 * @return User the static model class
	 */
	public static function model($className = __CLASS__) {
		return parent::model($className);
	}

	/**
	 * @return string the associated database table name
	 */
	public function tableName() {
		return '{{user}}';
	}

	/**
	 * @return array validation rules for model attributes.
	 */
	public function rules() {
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
		array('username,  email, first_name, last_name,', 'required', 'message' => t('MSG_REQUIRED', 'messages')),
		array('active', 'numerical', 'integerOnly' => true, 'message' => t('MSG_WRONG_NUMBER', 'messages')),
		array('first_name, last_name', 'length', 'max' => '30', 'tooLong' => t('MSG_STRING_TOO_LONG', 'messages')),
		array('password, email', 'length', 'max' => '64', 'tooLong' => t('MSG_STRING_TOO_LONG', 'messages')),
		array('create_date, update_date, role, user_role', 'safe'),
		array('user_role', 'length', 'max' => 1000, 'tooLong' => t('MSG_STRING_TOO_LONG', 'messages')),
		// The following rule is used by search().
		// Please remove those attributes that should not be searched.
		array('keyword, username, user_role, active, email', 'safe', 'on' => USER::SCENARIO_SEARCH),
		array('keyword', 'length', 'max' => 100, 'tooLong' => t('MSG_STRING_TOO_LONG', 'messages')),
		array('username', 'length',
		'min' => '3',
		'tooShort' => t('MSG_STRING_TOO_SHORT', 'messages'),
		'max' => '64',
		'tooLong' => t('MSG_STRING_TOO_LONG', 'messages')),
		array('username', 'match', 'allowEmpty' => false, 'pattern' => '/^[A-Za-z0-9_.]+$/', 'on' => array(User::SCENARIO_CREATE, User::SCENARIO_USER_REGISTER), 'message' => t('MSG_USERNAME_NOT_VALID', 'messages')),
		array('username, email', 'unique', 'message' => t('MSG_UNIQUE', 'messages'), 'on' => array(self::SCENARIO_CREATE, self::SCENARIO_UPDATE_USER, self::SCENARIO_USER_REGISTER)),
		array('email', 'email', 'message' => t('MSG_WRONG_EMAIL', 'messages')),
		// Both passwords always must match, but are only required on create!
		array('new_password, new_password_repeat', 'required', 'on' => array(User::SCENARIO_CREATE), 'message' => t('MSG_REQUIRED', 'messages')),
		array('new_password', 'length',
		'min' => '6', 'tooShort' => t('MSG_STRING_TOO_SHORT', 'messages'),
		'max' => '30', 'tooLong' => t('MSG_STRING_TOO_LONG', 'messages')),
		array('new_password_repeat', 'compare', 'compareAttribute' => 'new_password', 'message' => t('MSG_WRONG_CONFIRM_PASSWORD', 'messages')),
		array('new_password_repeat', 'length',
		'min' => '6', 'tooShort' => t('MSG_STRING_TOO_SHORT', 'messages'),
		'max' => '30', 'tooLong' => t('MSG_STRING_TOO_LONG', 'messages')),
		// Make new_password_repeat safe. If it doesn't appear in any other rule, it's considered not safe!
		array('new_password_repeat', 'safe'),
		array('auth_assignments', 'safe'),
		array('securityCode', 'length', 'max' => '100', 'tooLong' => t('MSG_STRING_TOO_LONG', 'messages')),
		array('securityCode', 'captcha', 'on' => self::SCENARIO_USER_REGISTER, 'message' => t('MSG_INCORECT_SECURITY_CODE', 'messages')),
		array('securityCode', 'safe', 'on' => self::SCENARIO_USER_REGISTER),
		array('auth_assignments', 'required', 'message' => t('MSG_REQUIRED', 'messages'), 'on' => USER::SCENARIO_CREATE . ',' . User::SCENARIO_UPDATE_USER)
		);
	}

	/**
	 * @return array relational rules.
	 */
	public function relations() {
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
		//'yiiAuthItems' => array(self::MANY_MANY, 'AuthItem', 'yii_auth_assignment(userid, itemname)'),
	    'yiiAuthItems' => array(self::MANY_MANY, 'AuthItem', '{{auth_assignment}}(userid, itemname)'),
	    'user_assignment' => array(self::HAS_MANY, 'AuthAssignment', 'itemname'),
	    'cmsClients' => array(self::MANY_MANY, 'Client', '{{client_assignment}}(userid, client_id)'),
	    'userFiles' => array(self::HAS_MANY, 'UserAndFile', 'user_id'),
		//'roles' => array(self::BELONGS_TO, 'AuthItem','auth_item_id'),
		);
	}

	/**
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels() {
		return array(
	    'id' => t('LBL_ID', 'user'),
	    'username' => t('LBL_USERNAME', 'user'),
	    'password' => t('LBL_OLD_PASSWORD', 'user'),
	    'email' => t('LBL_EMAIL', 'user'),
	    'first_name' => t('LBL_FIRST_NAME', 'user'),
	    'last_name' => t('LBL_LAST_NAME', 'user'),
	    'active' => t('LBL_ACTIVE', 'user'),
	    'created_date' => t('LBL_CREATE_DATE', 'user'),
	    'updated_date' => t('LBL_UPDATE_DATE', 'user'),
	    'updated_by' => t('LBL_UPDATED_BY', 'user'),
		//'full_name' => t('LBL_NAME', 'user'),
	    'fullname' => t('LBL_NAME', 'user'),
	    'new_password' => t('LBL_PASSWORD', 'user'),
	    'new_password_repeat' => t('LBL_CONFIRM_PASSWORD', 'user'),
	    'auth_assignments' => t('LBL_ROLE', 'user')
		);
	}

	public function isSuperAdmin() {
		$auth = Yii::app()->authManager;
		$arr_role = $auth->getAuthItems(LGConstant::AUTH_ITEM_ROLE, $this->id);
		return array_key_exists(Roles::SUPER_ADMIN, $arr_role) || app()->user->checkSuperAdmin();
	}
	
	public function isAdmin() {
		$auth = Yii::app()->authManager;
		$arr_role = $auth->getAuthItems(LGConstant::AUTH_ITEM_ROLE, $this->id);
		return array_key_exists(Roles::ADMINISTRATOR, $arr_role);
	}

	public function isManager() {
		$auth = Yii::app()->authManager;
		$arr_role = $auth->getAuthItems(LGConstant::AUTH_ITEM_ROLE, $this->id);
		return array_key_exists(Roles::MANAGER, $arr_role);
	}

	public function isEditor() {
		$auth = Yii::app()->authManager;
		$arr_role = $auth->getAuthItems(LGConstant::AUTH_ITEM_ROLE, $this->id);
		return array_key_exists(Roles::EDITOR, $arr_role);
	}

	public function isSubmitter() {
		$auth = Yii::app()->authManager;
		$arr_role = $auth->getAuthItems(LGConstant::AUTH_ITEM_ROLE, $this->id);
		return array_key_exists(Roles::SUBMITTER, $arr_role);
	}
	
	public function isTranslator() {
		$auth = Yii::app()->authManager;
		$arr_role = $auth->getAuthItems(LGConstant::AUTH_ITEM_ROLE, $this->id);
		return array_key_exists(Roles::TRANSLATOR, $arr_role);
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions.
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public function search() {
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.
		$this->keyword = trim($this->keyword);
		$criteria = new CDbCriteria;

		$criteria->addSearchCondition('concat(first_name, " ", last_name)', $this->keyword, true, 'OR');
		$criteria->addSearchCondition('username', $this->keyword, true, 'OR');
		$criteria->compare('user_role', $this->user_role);
		$criteria->compare('active', $this->active);

		$sort = new CSort;
		$sort->defaultOrder = array('id' => CSort::SORT_DESC);
		$sort->attributes = array(
	    '*',
	    'fullname' => array(
		'asc' => 'first_name, last_name',
		'desc' => 'first_name DESC, last_name DESC',
		)
		);

		return new CActiveDataProvider($this, array(
	    'criteria' => $criteria,
	    'pagination' => array(
		'pageSize' => LGHelpers::getPageSize($this->count()),
		),
	    'sort' => $sort
		));
	}

	public function beforeSave() {
		if (parent::beforeSave()) {

			$current_date = date(LGConstant::DATE_FORMAT_FOR_DATABASE);

			//Get user is logging
			$logedInUser = User::model()->findByPk(Yii::app()->user->id);

			if ($this->isNewRecord) {
				$this->create_date = $current_date;

				if (isset($logedInUser)) {
					$this->created_by = $logedInUser->username;
				}
				$this->active_code = genUniqueCode();
			}

			$this->update_date = $current_date;

			if (isset($logedInUser)) {
				$this->updated_by = $logedInUser->username;
			}

			if (!empty($this->new_password)) {
				$this->password = hashPassword($this->new_password);
			}

			$this->setIsNewRecord(false);
			return true;
		} else {
			return false;
		}
	}

	protected function afterSave() {
		parent::afterSave();

		//If scenario is not 'change status', will revoke all old roles and add new roles
		if ($this->scenario != USer::SCENARIO_CHANGE_ACTIVATION_STATUS) {

			$userId = $this->id;
			$auth = Yii::app()->authManager;

			//Get auth items of old roles
			$arr_role = $auth->getAuthItems(LGConstant::AUTH_ITEM_ROLE, $userId);

			//$arrRole is array of new roles
			$arrRole = $this->auth_assignments;

			//revoke all old roles
			if (count($arr_role) > 0) {
				foreach ($arr_role as $role)
				$auth->revoke($role->getName(), $userId);
				$this->saveAttributes(array('user_role' => ''));
			}

			//assign new roles
			if ($arrRole != '') {
				$role = '';

				if (is_array($arrRole)) {
					foreach ($arrRole as $id) {
						$authAssign = new AuthAssignment;
						$authAssign->itemname = $id;
						$authAssign->userid = $this->id;
						$authAssign->save();
						$role .= $id . ' ';
					}
				} else {
					$authAssign = new AuthAssignment;
					$authAssign->itemname = $arrRole;
					$authAssign->userid = $this->id;
					$authAssign->save();
					$role .= $arrRole . ' ';
				}

				return $this->saveAttributes(array('user_role' => $role));
			}
			return false;
		}
	}

	protected function afterFind() {
		// convert to display format
		$this->fullname = $this->first_name . ' ' . $this->last_name;

		$updateDateTimeSpan = strtotime($this->update_date);
		$this->update_date = date(LGConstant::DATE_FORMAT, $updateDateTimeSpan);
		if ($this->update_date == LGConstant::DATE_DEFAULT) {
			$this->update_date = '';
		}
		parent::afterFind();
	}

	public function getRoles($user_id) {
		$user = $this->findByAttributes(array('username' => $this->username), 'username=:name', array(':name' => $user_id));
		$size = sizeof($user->yiiAuthItems);

		if ($size > 0) {
			$lstRole = '';
			for ($i = 0; $i < sizeof($user->yiiAuthItems); $i++)
			$lstRole .= CHtml::encode($user->yiiAuthItems[$i]->name) . ((sizeof($user->yiiAuthItems) > 1 and $i < sizeof($user->yiiAuthItems) - 1) ? '<br />' : '');//change ',' -> '<br />'
			return $lstRole;
		}

		return '';
	}

	//Getter/setter for checkbox list
	public function getAuth_Assignments() {
		if (!isset($_POST['User'])) {
			$ids = array();
			foreach ($this->yiiAuthItems as $c)
			$ids[] = $c->name;
			return $ids;
		}
	}

	public function setAuth_Assignments($values) {
		$this->auth_Assignments = $values;
	}

	//full_name getter/setter
	public function getFull_Name() {
		return $this->first_name . ' ' . $this->last_name;
	}

	/**
	 * Static Function retrun String Roles of the User
	 * @param bigint $uid
	 * @return string
	 */
	public static function getStringRoles($uid = 0) {
		$roles = Rights::getAssignedRoles($uid, true);
		$res = array();

		foreach ($roles as $r) {
			$res[] = $r->name;
		}
		if (count($res) > 0)
		return implode(',', $res);
		else
		return '';
	}

	public function getRolesString() {
		return ($this->getAttribute('user_role'));
	}

	public function setRolesString($value) {
		$this->saveAttributes(array('user_role' => $value));
	}

	public function validatePassword($password) {
		return hashPassword($password) === $this->password;
	}

	public function findAllUsersByName($name = '') {

		if ($name != '') {

			$criteria = new CDbCriteria();

			// TODO: Changed by Kien.Tran
			$criteria->compare('username', $name, true);

			//$criteria->addCondition('username like :username');
			//$criteria->params = array(':username' => '%' . mysql_real_escape_string($name) . '%');
			//$criteria->params = array(':username' => '%' . $name . '%');
			return $this->findAll($criteria);
		} else {
			return $this->findAll();
		}
	}

	/**
	 * find users which are specified by $email.
	 * @param type $email
	 * @param type $partialMatch whether the value should consider partial text match
	 * 		   (using LIKE and NOT LIKE operators). Defaults to false, meaning exact comparison.
	 * @return type
	 */
	public function findUserByEmail($email, $partialMatch = true) {
		$criteria = new CDbCriteria();

		$criteria->compare('email', $email, $partialMatch);

		return $this->findAll($criteria);
	}

	/**
	 *
	 * @return array
	 */
	public static function getUserWillBeSentSignUpEmail() {
		$arrRecievedUser = Yii::app()->params['RoleWillRecievedSignUpEmail'];

		$criteria = new CDbCriteria();
		$criteria->compare('active', LGConstant::ACTIVATION_STATUS_YES);
		$criteria->addInCondition('user_role', $arrRecievedUser);

		return self::model()->findAll($criteria);
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions.
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public static  function searchUserRole($userRole) {
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.
		$model = User::model();

		$criteria = new CDbCriteria;

		$criteria->compare('user_role', $userRole);
		$criteria->compare('active', LGConstant::ACTIVATION_STATUS_YES);
		$sort = new CSort;
		$sort->defaultOrder = array('username' => CSort::SORT_DESC);

		return new CActiveDataProvider($model, array(
	    'criteria' => $criteria,
	    'pagination' => false,
	    'sort' => $sort
		));
	}

	/**
	 * Retrieves a list of users and file. Left join User
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public static  function searchUserRoleWithFile($userRole, $fileID) {

		$model = User::model();
		$userAdnFile = UserAndFile::model();

		$criteria = new CDbCriteria;
		$criteria->alias = 't';
		$criteria->compare('user_role', $userRole);
		//$criteria->with = array('userFiles');
		//$criteria->together = true;
		//$criteria->join = "LEFT JOIN ".  $userAdnFile->tableName(). ' userFiles ON t.id = userFiles.user_id';

		$criteria->compare('userFiles.file_id', $fileID);
		$sort = new CSort;
		$sort->defaultOrder = array('username' => CSort::SORT_DESC);

		return new CActiveDataProvider($model, array(
	    'criteria' => $criteria,
	    'pagination' => false,
	    'sort' => $sort
		));
	}
}
